package com.wedo.mall.ptr;
import android.view.View;

import com.e.library.adapter.EAdapter;
import com.e.library.http.EClient;
import com.e.library.http.EObserver;
import com.e.library.http.EResponse;
import com.jcodecraeer.xrecyclerview.ProgressStyle;
import com.jcodecraeer.xrecyclerview.XRecyclerView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Android下拉刷新上拉加载组件
 * @author lxy
 * @time 2017/7/4  12:17
 */
public final class Pull2Refresh<Data> implements XRecyclerView.LoadingListener{

    private View mEmptyView;
    private XRecyclerView xRecyclerView;

    private int mPage = 1;
    private int mPageLimit = 10;//每页大小
    private boolean hasMore = false;
    private Map<String,String> mParams = new HashMap<>();

    private String mUrl;
    private Class<Data> mClazz;
    private EAdapter<Data> mAdapter;
    private List<Data> mDatas;
    private String key = "list";//json key

    /**自定义HTTP回调*/
    private EObserver mCustomObserver;

    public Pull2Refresh(){}

    public Pull2Refresh<Data> widget(XRecyclerView xRecyclerView){
        this.xRecyclerView = xRecyclerView;
        return this;
    }

    public Pull2Refresh<Data> url(String url){
        this.mUrl = url;
        return this;
    }

    public Pull2Refresh<Data> clazz(Class<Data> clazz){
        this.mClazz = clazz;
        return this;
    }

    public Pull2Refresh<Data> adapter(EAdapter<Data> adapter){
        this.mAdapter = adapter;
        return this;
    }

    public Pull2Refresh<Data> param(String key, String value){
        mParams.put(key,value);
        return this;
    }

    public Pull2Refresh<Data> params(Map<String,String> params){
        mParams.putAll(params);
        return this;
    }

    public Pull2Refresh<Data> removeParam(String key){
        mParams.remove(key);
        return this;
    }

    public Pull2Refresh<Data> key(String key){
        this.key = key;
        return this;
    }

    public Pull2Refresh<Data> limit(int size){
        this.mPageLimit = size;
        return this;
    }

    /**自定义HTTP回调*/
    public Pull2Refresh<Data> observer(EObserver observer){
        mCustomObserver = observer;
        return this;
    }

    public Pull2Refresh<Data> emptyWidget(View view){
        this.mEmptyView = view;
        return this;
    }

    /**设置点击空页面重新刷新，先调用emptyWidget()函数再调用该函数*/
    public Pull2Refresh<Data> retry(){
        checkNotNull(mEmptyView,"you must call empty(View) first");
        mEmptyView.setClickable(true);
        mEmptyView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mEmptyView.setVisibility(View.GONE);
                refresh();
            }
        });
        return this;
    }

    public Pull2Refresh<Data> build(){
        checkNotNull(xRecyclerView,"widget XRecyclerView must not null");
        checkNotNull(mUrl,"url must not null");
        checkNotNull(mClazz,"clazz must not null");
        checkNotNull(mAdapter,"adapter must not null");

        if (mAdapter.get() != null){
            mDatas = mAdapter.get();
        }else {
            mDatas = new ArrayList<>();
            mAdapter.set(mDatas);
        }

        putPage();
        //limit(mPageLimit);
        xRecyclerView.setAdapter(mAdapter);
        xRecyclerView.setLoadingMoreEnabled(true);
        xRecyclerView.setPullRefreshEnabled(true);
        xRecyclerView.setLoadingListener(this);
        xRecyclerView.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader);
        xRecyclerView.setLoadingMoreProgressStyle(ProgressStyle.BallSpinFadeLoader);
        return this;
    }

    public Pull2Refresh<Data> done(){
        this.build();
        xRecyclerView.refresh();
        return this;
    }

    public Pull2Refresh<Data> refresh(){
        checkNotNull(xRecyclerView,"widget XRecyclerView must not null");
        xRecyclerView.refresh();
        return this;
    }

    private void clear(){
        mPage =1;
        putPage();
        mDatas.clear();
        mAdapter.notifyDataSetChanged();
    }

    private void putPage(){
        mParams.put("page",String.valueOf(mPage));
    }

    public List<Data> datas(){
        return mDatas;
    }

    @Override
    public void onRefresh() {
        clear();
        request();
    }

    @Override
    public void onLoadMore() {
        if (hasMore){
            mPage++;
            putPage();
            request();
        }else {
            onRefreshComplete();
        }
    }

    private void onRefreshComplete(){
        xRecyclerView.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (isEmpty(mDatas) && mEmptyView !=null){
                    mEmptyView.setVisibility(View.VISIBLE);
                    xRecyclerView.setLoadingMoreEnabled(false);
                    xRecyclerView.setNoMore(false);

                }else if (!isEmpty(mDatas) && mEmptyView !=null){
                    mEmptyView.setVisibility(View.GONE);
                }
                xRecyclerView.setVisibility(View.VISIBLE);
                xRecyclerView.refreshComplete();
                xRecyclerView.loadMoreComplete();
                if (!isEmpty(mDatas)){
                    xRecyclerView.setNoMore(!hasMore);
                }
                //
            }
        },200);
    }

    private void checkNotNull(Object obj, String msg){
        if (obj == null){
            throw new IllegalArgumentException(msg);
        }
    }

    private boolean isEmpty(List<?> list){
        return list ==  null || list.isEmpty();
    }

    /**默认的HTTP回调*/
    private EObserver mObserver = new EObserver() {
        @Override
        public void successful(EResponse response) {
            mPageLimit = response.page_limit;
            List<Data> list = response.list(mClazz);
            finish(list);
        }

        @Override
        public void failure(String msg) {
            finish(null);
        }
    };

    private void request(){
        if (mCustomObserver == null){
            EClient.with().post(mUrl, mParams,mObserver);
        }else {
            /**使用自定义回调，使用自定义回调请一定要自行调用{@link #finish(List)}*/
            EClient.with().post(mUrl, mParams,mCustomObserver);
        }
    }

    public void finish(List<Data> list){
        if (!isEmpty(list)){
            hasMore = list.size()== mPageLimit;
            mDatas.addAll(list);
            mAdapter.notifyDataSetChanged();
            onRefreshComplete();
        }else {
            hasMore = false;
            onRefreshComplete();
        }
    }

}
